

#include<windows.h>


namespace xy{

		
	class Exception{
		
		const char *msg;
		
		public:
			Exception(const char *msg){
				this->msg = msg;
			}
			const char *what(){
				return this->msg;
			}
	};
	
	


	class File{
		
		char *file_name;
		HANDLE file_handle;
		
		
		
		public:
			File(char *file_name=nullptr):file_name(file_name),
			file_handle(INVALID_HANDLE_VALUE){
				
				this->file_name = file_name;
				
				this->file_handle = CreateFile(this->file_name,
									GENERIC_ALL,
									0,
									nullptr,
									OPEN_ALWAYS,
									FILE_ATTRIBUTE_NORMAL,
									nullptr
									);
				
				if(this->file_handle == INVALID_HANDLE_VALUE){
					throw Exception("打开文件失败");
				}
				
			}
			
			char* get_file_name(){
				return this->file_name;
			}
			
			HANDLE get_handle(){
				return this->file_handle;
			}
			
			void close_handle(){
				CloseHandle(this->file_handle);
				this->file_handle = INVALID_HANDLE_VALUE;
			}
			
			virtual ~File(){
				
				if(this->file_handle != INVALID_HANDLE_VALUE){
					this->close_handle();
				}
				
			}
			
	};
	
	
	//template<class T>
	class Mapping{
		
		HANDLE map_handle = nullptr;

		File *file = nullptr;
		
		DWORD64 size = 0;
		
		DWORD64 offset = 0;
		
		LPVOID view = nullptr;
		
		public:
			
			Mapping(DWORD64 offset=0,DWORD64 size=0,File *file=nullptr,const char *shared_name=nullptr){
				this->offset = offset;
				this->size = size;
				if(file){
					this->file = file;
					this->map_handle = CreateFileMapping(this->file->get_handle(),
										nullptr,
										PAGE_EXECUTE_READWRITE,
										this->size >> 32,
										this->size,
										shared_name
										);
		
				}else{
					this->map_handle = CreateFileMapping(INVALID_HANDLE_VALUE,
										nullptr,
										PAGE_EXECUTE_READWRITE,
										this->size >> 32,
										this->size,
										shared_name
										);
				}
				
				if(!this->map_handle){
					throw Exception("创建映射失败");
				}
				
				this->view = MapViewOfFile(this->map_handle,
									FILE_MAP_ALL_ACCESS|FILE_MAP_EXECUTE,
									this->offset>>32,
									this->offset,
									this->size
									);
				if(!this->view){
					throw Exception("创建映射视图失败");
				}
				
			}
			
			/*LPVOID data(){

				return this->view;
				
			}*/
			
			template<class T>
			T data(){
				return static_cast<T>(this->view);
			}
			
			HANDLE get_handle(){
				return this->map_handle;
			}
			
			void close_handle(){
				CloseHandle(this->map_handle);
				this->map_handle = nullptr;
			}
			
			void close_view(){
				UnmapViewOfFile(this->view);
				this->view = nullptr;
			}
			
			virtual ~Mapping(){
				if(this->view){
					close_view();
				}
				
				if(this->map_handle){
					close_handle();
				}
				
			}
		
	};
	
}


#include<iostream>
using namespace std;



int main(){
	
	
	xy::Mapping m(0,1024);
	
	int* d = m.data<int*>();
	d[0] = 100;
	
	cout << d[0] << endl;
	
	xy::File f("test1.txt");
	xy::Mapping m2(0,1024,&f);
	
	int* d2 = m2.data<int*>();
	d2[1]=100;
	cout << d2[1] << endl;
	DWORD64 *d3 = m2.data<DWORD64*>();
	d3[0] = 999;
	cout << d3[0] << endl;
	cout << d2[0] <<endl;
	cout << d2[1] <<endl;
	
	char *s = m2.data<char*>();
	for(int i=0;i<1024;i++){
		s[i] = 'A';
	}
	
	
	
	//m2.data<void (*)()>();
	//m2.data<void (*)()>()();
	
	
	return 0;
}




